/*
 *  Splitsbrowser - IOF standard XML file format loader
 *
 *  Original Copyright (C) 2003  Dave Ryder
 *
 * This  library is free software; you can redistribute it and/or  modify it
 * under the terms of the GNU Library General Public  License as published by
 * the Free Software Foundation; either  version 2 of the License, or (at your
 * option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA 02111-1307, USA.
 */
/*
 * Version control info - Do not edit
 * Created:    Dave Ryder
 * Version:    $Revision: 1.1 $
 * Changed:    $Date: 2003/09/18 19:33:13 $
 * Changed by: $Author: daveryder $
 */
package org.uk.splitsbrowser.server.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

import org.uk.splitsbrowser.shared.results.AgeClass;
import org.uk.splitsbrowser.shared.results.Course;
import org.uk.splitsbrowser.shared.results.EventResults;
import org.uk.splitsbrowser.shared.results.Result;
import org.uk.splitsbrowser.shared.results.Time;

import org.uk.splitsbrowser.server.io.iofxml.*;
import org.uk.splitsbrowser.server.io.iofxml.v203.ClassResult;
import org.uk.splitsbrowser.server.io.iofxml.v203.PersonResult;
import org.uk.splitsbrowser.server.io.iofxml.v203.ResultList;
import org.uk.splitsbrowser.server.io.iofxml.v203.SplitTime;
import org.uk.splitsbrowser.server.io.iofxml.v203.TeamResult;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;


import org.uk.splitsbrowser.shared.SplitsbrowserException;

/**
 * Loads event details from an IOF standard XML format file.
 * 
 * @author D Ryder
 * @modified April 2003
 */
public class IOFXMLEventLoader extends EventLoader {
	private AgeClass ageClass = null;
	private Course course = null;
	private EventResults event;

	/**
	 * Constructor for the CSVEventLoader object
	 * 
	 * @param newEvent
	 *            Description of the Parameter
	 */
	public IOFXMLEventLoader() {
	}

	/**
	 * Load results in IOF format from a specified file.
	 * 
	 * @param base
	 *            base URL
	 * @param fileName
	 *            filename
	 * @param urlInput
	 *            Is filename a URL or a local file
	 * @param zipped
	 *            Is the file zipped
	 * @param byCourse
	 *            Description of the Parameter
	 * @exception IOException
	 * @exception Exception
	 */
	public void loadEvent(EventResults newEvent, String fileName, boolean urlInput,
                          int newbyCourse) throws IOException, SplitsbrowserException
    {
        event = newEvent;

        BufferedReader reader;
        
        reader = openReader(fileName, urlInput);
        
        try {
            JAXBContext jc = JAXBContext.newInstance ("jaxbclasses");
            Unmarshaller u = jc.createUnmarshaller ();
 
            ResultList resultList = (ResultList) u.unmarshal (reader);

            Iterator<ClassResult> iterator = resultList.getClassResult().iterator();
                       
        	while (iterator.hasNext()) {
        		parseClassResult(iterator.next());
        	}

       } catch (JAXBException e) {
           e.printStackTrace();
       }
    }

	private void parseClassResult(ClassResult classResult) throws SplitsbrowserException {
    	   			//populate class result properties
    	   
    	   
                if (classResult.getPersonResultOrTeamResult() instanceof TeamResult) {
                	 // We do not currently support team results
                    throw new SplitsbrowserException("Team Results not supported currently"); 
                } else {
                	// Class name or class Id or event class
                	
                	ageClass = new AgeClass(classResult.getClassShortName().getValue() );
                	

                Iterator<PersonResult> personResultIterator = (Iterator) classResult.getPersonResultOrTeamResult().iterator();
                
            	while (personResultIterator.hasNext()) {
            		PersonResult p = personResultIterator.next();
            		
            		//We use the short club name
            		String club = p.getClub().getShortName().getValue();
            		
            		//Id of country is its iso country code
            		String country =p.getCountry().getCountryId().getValue();
            		
            		org.uk.splitsbrowser.server.io.iofxml.v203.Result r = p.getResult();
            		
            		boolean ok = r.getCompetitorStatus().getValue() == "OK";           		
            		String variation = r.getCourseVariationId();
            		
            		Time startTime = timeFromString(r.getStartTime().getClock().getValue(), 
            				                        r.getStartTime().getClock().getClockFormat()); 
            		
            		if (r.getSplitTime() == null ) {
            		    boolean hasSplits= false; 
            		} else { 
            			Iterator<SplitTime> splitIterator = (Iterator<SplitTime>) r.getSplitTime().iterator();
            			while (splitIterator.hasNext()) {
            				Split s = new Split(splitIterator.next());
            			}
            		}
            		
            		// If we have control codes then find course with same controls or create one if none exists
            		
            		
            	}  
                }

       }

	private Result parseResult(String name, String clubName,
			PersonResult personResult) throws Exception {
		Time startTime = Time.NULLTIME;
		Time finishTime = Time.NULLTIME;
		Time totalTime = Time.NULLTIME;
		boolean validRun = true;
		boolean gotSplits = false;
		double courseLength = 0.0;
		String club = null;
		Vector<Split> splits = new Vector<Split>(15, 10);

		Time[] totalTimes = null;

		if (gotSplits) {
			totalTimes = new Time[splits.size()];

			for (int i = 0; i < splits.size(); i++) {
				totalTimes[i] = (Time) splits.elementAt(i).totalTime;
			}
		}

		if (course == null) {
			// course =new Course(courseName, numControls, distance, climb);

			// set the control codes
			for (int i = 0; i < splits.size(); i++) {
				// String controlCode = splits.c;
				String controlCode = null;

				if (controlCode != null) {
					course.addControlCode(i + 1, controlCode);
				}
			}

			course = event.addCourse(course);
			ageClass = course.addAgeClass(ageClass);
		}

		// Create the result
		Result result = new Result(name, club, course, ageClass, totalTimes,
				startTime, validRun);
		ageClass.addResult(result);

		return (result);
	}

	/** Parse a time string from IOF XML file */
	private static Time timeFromString(String str, String format)
			throws SplitsbrowserException {
		StringTokenizer st = new StringTokenizer(str, ":");

		int hours = 0;
		int min = 0;
		int sec = 0;
		Time t;

		try {
			if (format.compareToIgnoreCase("HH:MM:SS") == 0) {
				hours = Integer.valueOf(st.nextToken()).intValue();
				min = Integer.valueOf(st.nextToken()).intValue();
				sec = Integer.valueOf(st.nextToken()).intValue();
			} else if (format.compareToIgnoreCase("HH:MM") == 0) {
				hours = Integer.valueOf(st.nextToken()).intValue();
				min = Integer.valueOf(st.nextToken()).intValue();
			} else if (format.compareToIgnoreCase("MM:SS") == 0) {
				min = Integer.valueOf(st.nextToken()).intValue();
				sec = Integer.valueOf(st.nextToken()).intValue();
			} else {
				throw new SplitsbrowserException("Invalid time format attribute " + format);
			}

			t = new Time((hours * 60) + min, sec);
		} catch (Exception e) {
			throw (new SplitsbrowserException("Invalid time" + e.getMessage()));
		}

		return (t);
	}

	/** Helper class to hold data for an individual split */
	class Split {
		public String controlCode;
		public Time totalTime;
		public int sequence;

		public Split(SplitTime s) throws SplitsbrowserException {
			controlCode = s.getControlCode();
			totalTime = IOFXMLEventLoader.timeFromString(
					s.getTime().getValue(), s.getTime().getTimeFormat());

			try {
				sequence = Integer.parseInt(s.getSequence());
			} catch (NumberFormatException e) {
				throw (new SplitsbrowserException("Invalid split sequence number" + " "
						+ s.getSequence()));
			}

		}

	}
}
